#ifndef MAINPLOT3D_H
#define MAINPLOT3D_H

#include <qwt3d_surfaceplot.h>
#include <qwt3d_function.h>
#include <QVector>
#include "TLabel.h"

class Bar3D;


class MainPlot3D : public Qwt3D::SurfacePlot
{
    Q_OBJECT

    class Plot3DFcn : public Qwt3D::Function
    {
        QVector< double > x;
        QVector< double > y;
        QVector< double > z;

        int nodes;
        int timeline;

        int xMin;
        int yMin;
        int xMax;
        int yMax;

    public:
        Plot3DFcn( Qwt3D::SurfacePlot * sp, QVector< double > & val, int nd, int t ) :
            Function( sp ),
            nodes( nd ),
            timeline( t )
        {
            x.clear();
            for( int i=1; i <= nodes; ++i )
                x.append( i );

            y.clear();
            for( int i=1; i <= timeline; ++i )
                y.append( i );

            z = val;

            xMin = 1;
            yMin = 1;
        }

        Plot3DFcn( Qwt3D::SurfacePlot * sp, QVector< double > & val, QVector< double > & _rows, QVector< double > & _cols ) :
            Function( sp ),
            nodes( _rows.count() ),
            timeline( _cols.count() )
        {
            x = _rows;
            y = _cols;
            z = val;

            QVector< double > tmp = x;
            qSort( tmp );
            xMin = tmp.at( 0 );
            xMax = tmp.at( tmp.count()-1 );
            tmp = y;
            qSort( tmp );
            yMin = tmp.at( 0 );
            yMax = tmp.at( tmp.count()-1 );
            //setDomain( xMin, xMax, yMin, yMax );
        }

        double operator()( double _x, double _y )
        {
            int ind = ( int( _x ) - xMin )*timeline + int( _y ) - yMin;
            if( ind >= z.count() )
                int cp=1;
            return z.at( ind );
        }
    };

    int columns;
    int rows;

    bool useBars;
    Bar3D * bar;

    Plot3DFcn * fcn;
    QString axZ;
    QString axY;
    QString axX;

    double scaleX;
    double scaleY;
    double scaleZ;
    double zm;

    QString mainTitle;

public:
    explicit MainPlot3D( QWidget *parent = 0 );

    void SetTitle( const QString & s ) { mainTitle = s; setTitle( s ); }
    void SetScale( double x, double y, double z );
    void SetMeshColor( Qwt3D::RGBA rgba );
    Qwt3D::RGBA MeshColor() { return meshColor(); }

    void Init( QVector< double > & data, int _columns, int _rows );
    void Init( QVector< double > & data, QVector< double > & _cols, QVector< double > & _rows );
    void SetTitleZ( QString s );
    QString GetTitleZ() { return axZ; }
    void SetTitleY( QString s );
    QString GetTitleY() { return axY; }
    void SetTitleX( QString s );
    QString GetTitleX() { return axX; }
    void Reset();
    QWidget * Wgt() { return (QWidget*)this; }
    void UpdateGL3D();

    bool UseBars() { return useBars; }
    void UseBars( bool u );
    void ShowBarBorder( bool s );
    bool ShowBarBorder();

    void Show() { show(); }
    void BarConf( double r, double l );

    void SetTicX( LabelType t, QVector< double > * data = 0 );
    void SetTicY( LabelType t, QVector< double > * data = 0 );
    void SetTicZ( LabelType t, QVector< double > * data = 0 );

private:
    void adjustScale();
    
signals:
    void sgnScaleChanged(double,double,double);
    
public slots:

private slots:
    void procRotate( double x, double y, double z );
    void sltScaleChanged( double x, double y, double z );

};

#endif // MAINPLOT3D_H
